<template>
  <li>
    <label>
      <!-- (1) 想用用户的选择来决定选项框的状态
               这个用户的选择->变量(todo.done)，
               选项框的状态->checked
               把这两者绑定在一起就行了
           为什么一定要用个变量保存用户的选择？
           因为 用户有没有选中 在别处还有用处
      -->

      <input
        type="checkbox"
        :checked="todo.done"
        @change="handleCheck(todo.id)"
      />
      <span v-show="!todo.isEdit">{{ todo.title }}</span>

      <!-- (3) 这里不需要双向绑定，仅仅是需要向input框里填值
               再说这里如果用 v-model 也会报错，因为Vue不允许修改props传过来的数据
           (4) 正常如果事件、绑定太多，竖着分条写时，要把原生的放那个最上面，Vue的放下面     
               原生的是大哥，Vue是小弟
           (5) @blur是失去焦点事件，这里用blur是指焦点模糊了，没了 
               注意想要执行失去焦点事件首先得点进去集中焦点
           (6) 在事件传方法时，如果参数不止一个，是要用括号括起来的，就像正常调用方法一样
               如果要使用e.target.value在调用时参数一定要写$event，否则编译器怎么知道是是event参数        
      -->
      <input
        type="text"
        v-show="todo.isEdit"
        :value="todo.title"
        @blur="handleBlur(todo, $event)"
        ref="inputTitle"
      />
    </label>
    <button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>
    <button
      class="btn btn-edit"
      v-show="!todo.isEdit"
      @click="handleEdit(todo)"
    >
      编辑
    </button>
  </li>
</template>

<script>
import pubsub from "pubsub-js";

export default {
  name: "MyItem",
  props: ["todo"],
  methods: {
    /**
     * (2) 其实也可以使用 v-model双向绑定直接 v-model="todo.done"
     *     这样还可以直接去掉 :checked="todo.done" 因为使用v-model
     *     本来就可以初始化 选项框，初始值就是done的初始值
     *
     *     但是不推荐使用，依照严格的eslint检查，会直接报错
     *     因为它违背了原则：父组件传过来的数据是不能修改的，不能改回去
     * */
    handleCheck(id) {
      //  this.checkTodo(id)
      // this.$bus.$emit('checkTodo',id)
      pubsub.publish("checkTodo", id);
    },
    handleDelete(id) {
      if (confirm("确定删除吗？")) {
        // (8) 下面三种分别是父子传值、全局事件总线、消息的发布与订阅三种
        //  this.deleteTodo(id) ---- 方法名
        // this.$bus.$emit('deleteTodo',id) ---- 事件名
        pubsub.publish("deleteTodo", id);// ---- 消息名
      }
    },
    handleEdit(todo) {
      todo.isEdit = true;
      /**
       * (9) vc身上的$nextTick里面的回调可以在下一次DOM更新之后再执行
       *     这样就可以减少DOM更新和其他操作的顺序问题了
       *     因为如果我直接写的话DOM都没更新完成，必须得这个函数代码全执行完才行
       *     现在就可以在代码执行结束之前写DOM更新之后的操作代码了
       * */ 
      this.$nextTick(()=>{
         this.$refs.inputTitle.focus()
      })
    },
    handleBlur(todo, e) {
      todo.isEdit = false;
      if (!e.target.value.trim()) {
        alert("输入不能为空！");
        return;
      }
      // (7) 利用组件通信和回调可以数据更新回去，可以弥补不能修改props传过来的参数
      pubsub.publish("updateTodo", todo.id, e.target.value);
    },
  },
};
</script>

<style>
/*item*/
li {
  list-style: none;
  height: 36px;
  line-height: 36px;
  padding: 0 5px;
  border-bottom: 1px solid #ddd;
}
li label {
  float: left;
  cursor: pointer;
}
li label li input {
  vertical-align: middle;
  margin-right: 6px;
  position: relative;
  top: -1px;
}
li button {
  float: right;
  display: none;
  margin-top: 3px;
}
li:before {
  content: initial;
}
li:last-child {
  border-bottom: none;
}
li:hover {
  background: #ddd;
}
li:hover button {
  display: block;
}
</style>
